package com.imddy.spbatch001.utils;

import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpClientUtils {

	private static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);
	// 链接相关参数
	private static int socketTimeout = 300000;
	private static int connectTimeout = 300000;
	private static int connectionRequestTimeout = 300000;
	private static RequestConfig requestConfig = null;
	// 连接池相关参数
	private static int connMgrMaxTotal = 100;
	private static int connMgrMaxPerRoute = 50;
	private static PoolingHttpClientConnectionManager connMgr = null;
	
	static {
		requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout).build();
		connMgr = new PoolingHttpClientConnectionManager();
		connMgr.setDefaultMaxPerRoute(connMgrMaxPerRoute);
		connMgr.setMaxTotal(connMgrMaxTotal);
	}
	
	
	private static String doHttp(HttpRequestBase httpRequestBase) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		String responseContent = null;
		
		try {
			// 创建默认的httpClient实例.
			String scheme = httpRequestBase.getURI().getScheme();
			if (scheme.equalsIgnoreCase("https")) {
				DefaultHostnameVerifier hostnameVerifier;
				//logger.info(httpRequestBase.getURI().toString());
				try {
					PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpRequestBase.getURI().toString()));
					hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);
				} catch(Exception e) {
					//logger.info("发生了异常");
					hostnameVerifier = new DefaultHostnameVerifier(null);
				}
				//PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpRequestBase.getURI().toString()));
				//DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);
				//DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(null);
				httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).setConnectionManager(connMgr).build();
				//httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build();
			} else if (scheme.equalsIgnoreCase("http")) {
				httpClient = HttpClients.custom().setConnectionManager(connMgr).build();
				//httpClient = HttpClients.createDefault();
			} else {
				throw new IllegalArgumentException("url的scheme错误，必须是http或者https！ ");
			}
			httpRequestBase.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpRequestBase);
			// 如果这里有必要获取的是其他资料都可以在这里进行逻辑处理
			responseContent = EntityUtils.toString(response.getEntity(), "UTF-8");
			return responseContent;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					// EntityUtils.consume(response.getEntity());
					response.close();
				}
				// 这里不能关闭httpClient，这个会关链接池
				//if (httpClient != null) {
				//  httpClient.close();
				//}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return responseContent;
	}
	
	
	/**
	 *  sendHttpGet(url)
	 * @param url
	 * @return
	 */
	public static String sendHttpGet(String url) {
		return doHttp(new HttpGet(url));
	}
	
	/**
	 * sendHttpGet()
	 * @param url
	 * @param param key1=value1&key2=value2&key3=value3
	 * @return
	 */
	public static String sendHttpGet(String url, String param) {
		// 创建httpGet
		HttpGet httpGet = new HttpGet(url + '?' + param);
		
		return doHttp(httpGet);
	}
	
	/**
	 * sendHttpPost()
	 * @param url
	 * @param param key1=value1&key2=value2&key3=value3
	 * @return
	 */
	public static String sendHttpPost(String url, String param) {
		// 创建httpPost
		HttpPost httpPost = new HttpPost(url);
		try {
			StringEntity stringEntity = new StringEntity(param, "UTF-8");
			stringEntity.setContentType("application/x-www-form-urlencoded");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return doHttp(httpPost);
	}
	
	/**
	 * sendHttpGet
	 * @param url
	 * @param param 是个map<String, String>
	 * @return
	 */
	public static String sendHttpGet(String url, Map<String, String> param) {
		// 创建httpGet
		String paramStr = "";
		for (String key : param.keySet()) {
			String tmp = "";
			tmp = "&" + key + "=" + param.get(key);
			paramStr += tmp;
		}
		paramStr = paramStr.substring(1);
		HttpGet httpGet = new HttpGet(url + '?' + paramStr);

        return doHttp(httpGet);
	}
	
	/**
	 * sendHttpPost
	 * @param url
	 * @param param 是个map<String,String>
	 * @return
	 */
	public static String sendHttpPost(String url, Map<String, String> param) {
		// 创建httpPost
		HttpPost httpPost = new HttpPost(url);
		// 创建参数队列 
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        for (String key : param.keySet()) {
            nameValuePairs.add(new BasicNameValuePair(key, param.get(key)));   
        }
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));    
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return doHttp(httpPost);
	}
	
	public static String sendHttpPostJson(String url, String json) {
		// 创建httpPost
		HttpPost httpPost = new HttpPost(url);
		try {
			// StringEntity stringEntity = new StringEntity(param, "UTF-8");
			// stringEntity.setContentType("application/json");
			// stringEntity.setContentEncoding("UTF-8");
			// stringEntity.setContentType("application/json");
			StringEntity stringEntity = new StringEntity(json, ContentType.create("application/json", "UTF-8"));
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			e.printStackTrace();
		}
						
		return doHttp(httpPost);
	}

	
	

	public static void main(String[] args) {
		
		String url = "http://api.crpay.com/payapi/gateway";
		String param = "merchant_no=TOF00001&method=unified.trade.pay&version=1.0";
		Map map = new HashMap<String, String>();
		map.put("merchant_no", "TOF00001");
		map.put("method", "unified.trade.pay");
		map.put("version", "1.0");
		
		// 这个工具是走的链接池，但是在关闭httpClient会关闭连接池的地方已经注销
		
		//System.out.println(HttpClientUtils.sendHttpPost(url, map));
		//System.out.println(HttpClientUtils.sendHttpPost(url, param));
		//System.out.println(HttpClientUtils.sendHttpGet(url, map));
		
		System.out.println(HttpClientUtils.sendHttpGet("https://www.baidu.com"));
		System.out.println(HttpClientUtils.sendHttpGet("http://www.baidu.com/s?wd=aaa"));
		
		Map map2 = new HashMap<String, String>();
		map2.put("wd", "aaa");
		System.out.println(HttpClientUtils.sendHttpGet("http://www.baidu.com/s",map2));

		// doHttp是静态私有方法，不能使用多次，会报Connection pool shut down 
		System.out.println(HttpClientUtils.doHttp(new HttpGet("http://www.baidu.com/s?wd=aaa")));
		System.out.println(HttpClientUtils.doHttp(new HttpGet("https://www.baidu.com/")));
		System.out.println(HttpClientUtils.doHttp(new HttpGet("https://www.baidu.com/")));
		System.out.println(HttpClientUtils.sendHttpGet("https://www.cnblogs.com/hugo-zhangzhen/p/6858013.html"));
		System.out.println(HttpClientUtils.sendHttpGet("https://www.cnblogs.com/hugo-zhangzhen/p/6739658.html"));
		System.out.println(HttpClientUtils.sendHttpGet("https://www.cnblogs.com/hugo-zhangzhen/p/6737810.html"));
		System.out.println(HttpClientUtils.sendHttpGet("http://blog.csdn.net/xiechengfa/article/details/42016153"));
		

	}
	
}